package com.glp.work.flow.handler.flowable;

import com.glp.common.reponse.BaseResult;
import com.glp.work.flow.constant.APICode;
import com.glp.work.flow.constant.ProcessVariablesEnum;
import com.glp.work.flow.exception.APIException;
import com.glp.work.flow.pojo.RoleCodes;
import com.glp.work.flow.pojo.WfTaskAssignRole;
import com.glp.work.flow.pojo.WfTaskAssignUsers;
import com.glp.work.flow.service.OrderInfoService;
import com.glp.work.flow.service.client.PermissionClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.flowable.bpmn.model.Activity;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
import org.springframework.context.ApplicationContext;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 会签任务分配
 *
 * @author pengjia
 * @version 2020年8月7日 下午1:46:22
 */
@Slf4j
public class ExtMultiInstanceUserTaskActivityBehavior extends ParallelMultiInstanceBehavior {

    private static final long serialVersionUID = -7112310774349343540L;

    private ApplicationContext applicationContext;

    private String appId;
    private String userNo;

    public ExtMultiInstanceUserTaskActivityBehavior(Activity activity,
                                                    AbstractBpmnActivityBehavior innerActivityBehavior) {
        super(activity, innerActivityBehavior);
    }

    @Override
    protected int createInstances(DelegateExecution execution) {
        //是否是动态分配用户
        @SuppressWarnings("unchecked")
        List<String> userNos = (List<String>) execution.getVariables().get(ProcessVariablesEnum.DYNAMIC_USER_ASSIGN.name());
        String proDefId = execution.getProcessDefinitionId();
        String taskDefKey = execution.getCurrentActivityId();
        if (CollectionUtils.isEmpty(userNos)) {
            log.info("多实例流程判断多实例个数！");
            log.info("是否多实例：{}", execution.isMultiInstanceRoot());
            OrderInfoService orderInfoService = applicationContext.getBean(OrderInfoService.class);
            PermissionClient permissionService = applicationContext.getBean(PermissionClient.class);
            log.info("【多实例用户查询】查询被分配任务的角色！根据流程定义ID：{}，任务定义KEY：{}，", proDefId, taskDefKey);
            List<WfTaskAssignUsers> userList = orderInfoService.queryTaskAssignUsers(proDefId, taskDefKey);
            log.info("【多实例用户查询】查询被分配任务的用户！根据流程定义ID：{}，任务定义KEY：{}，", proDefId, taskDefKey);
            List<WfTaskAssignRole> roleList = orderInfoService.queryTaskAssignRoles(proDefId, taskDefKey);
            RoleCodes roleCodes = new RoleCodes();
            List<String> codes = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(roleList)) {
                for (WfTaskAssignRole wfTaskAssignRole : roleList) {
                    log.info("【多实例用户查询】角色对应的code:{}", wfTaskAssignRole.getRoleCode());
                    codes.add(wfTaskAssignRole.getRoleCode());
                }
                roleCodes.setRoleCodeList(codes);
                BaseResult<?> listBaseResult = permissionService.personInfosByRoleCodeList(roleCodes);
                if (listBaseResult.getCode() != 200) {
                    throw new APIException(APICode.ERROR, "【多实例用户查询】调用根据角色得到对应的用户列表失败！！");
                }
                log.info("【多实例用户查询】根据角色得到对应的用户信息:{}", listBaseResult);
                @SuppressWarnings("unchecked")
                List<Map<String, String>> data = (List<Map<String, String>>) listBaseResult.getData();
                for (Map<String, String> user : data) {
                    String userNo = user.get("userNo");
                    WfTaskAssignUsers users = new WfTaskAssignUsers();
                    users.setUserNo(userNo);
                    userList.add(users);
                }
            }
            userNos = userList.stream().map(WfTaskAssignUsers::getUserNo).collect(Collectors.toList());
            log.info("【多实例用户查询】流程定义ID：{}，任务定义KEY：{}，被分配任务的用户：{}", proDefId, taskDefKey, userNos);
            if (CollectionUtils.isEmpty(userNos)) {
                throw new APIException(APICode.NULL_PARAMETER, "【多实例用户查询】请分配会签相关的用户");
            }
            setLoopVariable(execution, NUMBER_OF_INSTANCES, userNos.size());
            setLoopVariable(execution, NUMBER_OF_COMPLETED_INSTANCES, 0);
            setLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES, userNos.size());
            return super.createInstances(execution);
        } else {
            setLoopVariable(execution, NUMBER_OF_INSTANCES, userNos.size());
            setLoopVariable(execution, NUMBER_OF_COMPLETED_INSTANCES, 0);
            setLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES, userNos.size());
            return super.createInstances(execution);
        }
    }


    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getUserNo() {
        return userNo;
    }

    public void setUserNo(String userNo) {
        this.userNo = userNo;
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

}
